﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ListenServer
{
    public partial class Form1 : Form
    {
        DuanKou d;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            d= new DuanKou("127.0.0.1",9190, dataGridView1);
            d.setResultMsg(resultMsg);
            d.Run();
            //Server server = new Server();

        }
        //表格点击触发事件
        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            Console.WriteLine(dataGridView1.Columns[e.ColumnIndex].Name);
            if (dataGridView1.Columns[e.ColumnIndex].Name.Contains("screenshot"))
            {
                //占击按钮操作
                Console.WriteLine("");
                //将机器接受到的字节数组转换为人可以读懂的字符串
                byte[] ins = new byte[1024 * 1024];
                ins = Encoding.UTF8.GetBytes("screenshot");
                byte[] bresult = d.sendIns(ins, dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString());
                if (bresult !=null)
                {
                    Img img = new Img(bresult);
                    img.ShowDialog();
                    //Utils.ShowImgByByte(bresult);
                }
               
               
            }
            else if (dataGridView1.Columns[e.ColumnIndex].Name.Contains("dllList"))
            {
                Console.WriteLine("dllIist 点击");
                byte[] ins = new byte[1024 * 1024];
                ins = Encoding.UTF8.GetBytes("dllList");
                byte[] bresult = d.sendDll(ins, dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString());
                DllList dllList = new DllList(bresult);
                dllList.ShowDialog();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            d.search(this.searchText.Text.ToString());
        }

        private void button2_Click(object sender, EventArgs e)
        {
            d.reset();
        }
    }


    public class DuanKou
    {
        int localProt { get; set; }
        string localIp { get; set; }
        static int cycleNumIndex = -1;
        static int cycleNum = 0;
        static AutoResetEvent myEvent = new AutoResetEvent(false);

        Socket serverSocket;
        //客户端
        List<socketObj> cilentSocket = new List<socketObj>();
        static bool m_StopListen = true;
        private byte[] bytes;
        Thread myThread;
        Thread listenClientThread;
        TextBox resultMsg;
        DataGridView dataGridView;


        public DuanKou(string localIp, int localProt,DataGridView dataGridView)
        {
            this.localIp = localIp;
            this.localProt = localProt;
            this.dataGridView = dataGridView;
        }

        public DuanKou()
        {
            this.localIp = "0.0.0.0";
            this.localProt = 8080;
        }

        public String Run()
        {
            bool isPort = PortHelper.portInUse(localProt, PortType.TCP);
            if (!isPort)
            {
                //服务器IP地址  
                IPAddress ip = IPAddress.Parse(localIp);
                serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                serverSocket.Bind(new IPEndPoint(ip, localProt));
                serverSocket.Listen(10000);
                this.resultMsg.AppendText("启动监听" + serverSocket.LocalEndPoint.ToString() + "成功\r\n");
                myThread = new Thread(Listen);
                myThread.Start(serverSocket);
                listenClientThread = new Thread(ListenCilent);
                listenClientThread.Start();



                return "已开启";
            }
            else
            {
                return "端口被占用";
            }
        }

        
        bool isImage = true;
        //发送指令
        public byte[] sendIns(byte[] b,string index)
        {
            try{
               
                foreach (socketObj obj in cilentSocket)
                {
                    Socket s = obj.socket;
                    
                    
                    if (obj.index.ToString().Equals(index))
                    {
                        cycleNumIndex = obj.index;
                        int i =  s.Send(b);
                        byte[] by = new byte[20];
                        int sent;
                        int count = 0;
                        int len = 0;
                        int dataleft = 20;
                        while (true)
                        {
                            try
                            {
                                sent = s.Receive(by,count, dataleft, SocketFlags.None);
                                string str = Encoding.Default.GetString(by);
                                
                                if (str.Contains("start"))
                                {
                                    string[] strArr = str.Split(';');
                                    str = strArr[0].Replace("start:", "");
                                    len = Convert.ToInt32(str);
                                    dataleft = len;
                                    count = 0;
                                    sent = 0;
                                    by = new byte[len];
                                    //Encoding.Default.GetBytes(strArr[1]).CopyTo(by,0);
                                }
                                //链接关闭
                                //if (sent ==0)
                                //{
                                //    if (s.Connected)
                                //    {
                                //        s.Close();
                                //    }

                                //    break;
                                //}
                                count += sent;
                                dataleft -= sent;
                                sendResultMsg("\r\n服务器端口接收数据----:" + count);
                                if (count == len)
                                {
                                    sendResultMsg("\r\n接收完成----:" + count);
                                    
                                    s.Send(Encoding.UTF8.GetBytes("end"));
                                    break;
                                }

                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message);
                                if (s.Connected)
                                {
                                    s.Close();
                                }

                                break;
                            }
                        }
                        //bytes = null;
                        cycleNumIndex = -1;
                        m_StopListen = true;
                        return by;
                    }

                }

            }
            catch (Exception ex)
            { 
                MessageBox.Show("发送指令失败,客户端未连接");
            }
            return null;
         }
        public byte[] sendDll(byte[] b, string index)
        {
            try
            {

                foreach (socketObj obj in cilentSocket)
                {
                    Socket s = obj.socket;


                    if (obj.index.ToString().Equals(index))
                    {
                        cycleNumIndex = obj.index;
                        int i = s.Send(b);
                        byte[] by = new byte[2048*1080];
                        int num = s.Receive(by, by.Length, SocketFlags.None);
                        string str = Encoding.Default.GetString(by);
                        sendResultMsg("\r\n接收完成----:" + num);
                        cycleNumIndex = -1;
                        m_StopListen = true;
                        return by;
                    }

                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("发送指令失败,客户端未连接");
            }
            return null;
        }

        public void Stop()
        {

            myThread.Suspend();
            sendResultMsg("关闭监听" + serverSocket.LocalEndPoint.ToString() + "成功\r\n");
            serverSocket.Close();
        }
       
        //用于反馈信息的框
        public void setResultMsg(TextBox resultMsg)
        {
            this.resultMsg = resultMsg;
        }
        public void sendResultMsg(string msg)
        {
            if (this.resultMsg != null)
            {
                if (this.resultMsg.InvokeRequired)
                {
                    // 当一个控件的InvokeRequired属性值为真时，说明有一个创建它以外的线程想访问它
                    Action<string> actionDelegate = (x) => { this.resultMsg.AppendText(x.ToString()); };
                    // 或者
                    // Action<string> actionDelegate = delegate(string txt) { this.label2.Text = txt; };
                    this.resultMsg.Invoke(actionDelegate, msg);
                }
                else
                {

                    this.resultMsg.AppendText(msg);
                }
            }
        }

        static bool IsSocketConnected(Socket s)
        {
            try
            {
                return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected);
            }
            catch (ObjectDisposedException ex)
            {
                return false;
            }
            
        }

        private void ListenCilent()
        {
            while (true)
            {
                List<int> indexs = new List<int>();
                for (int i = 0; i < cilentSocket.Count; i++)
                {
                    if (!IsSocketConnected(cilentSocket[i].socket))
                    {
                        indexs.Add(i);
                    }
                }
                //删除已连接的客户端
                for (int i = indexs.Count; i > 0; i--)
                {
                    cilentSocket.RemoveAt(indexs[i - 1]);
                }

                List<DataList> dlist = new List<DataList>();
                foreach (socketObj obj in cilentSocket)
                {
                    Socket s = obj.socket;
                    IPAddress clientIP = (s.RemoteEndPoint as IPEndPoint).Address;
                    int clientPort = (s.RemoteEndPoint as IPEndPoint).Port;
                    DataList data = new DataList(clientIP.ToString(), obj.name);
                    data.index = obj.index;
                    dlist.Add(data);
                }
                if (this.dataGridView != null)
                {

                    if (this.dataGridView.InvokeRequired)
                    {
                        // 当一个控件的InvokeRequired属性值为真时，说明有一个创建它以外的线程想访问它
                        Action<List<DataList>> actionDelegate = (x) => {
                            this.dataGridView.DataSource = null; this.dataGridView.DataSource = x;
                        };
                        // 或者
                        // Action<string> actionDelegate = delegate(string txt) { this.label2.Text = txt; };
                        this.dataGridView.Invoke(actionDelegate, dlist);
                    }
                    else
                    {

                        this.dataGridView.DataSource = dlist;
                    }
                }
                Thread.Sleep(5000);
            }
               
           
        }
        public void search(string text)
        {
            listenClientThread.Suspend();

            List<DataList> dlist = new List<DataList>();
            foreach (socketObj obj in cilentSocket)
            {
                if (obj.name.Contains(text))
                {
                    Socket s = obj.socket;
                    IPAddress clientIP = (s.RemoteEndPoint as IPEndPoint).Address;
                    int clientPort = (s.RemoteEndPoint as IPEndPoint).Port;
                    DataList data = new DataList(clientIP.ToString(), obj.name);
                    data.index = obj.index;
                    dlist.Add(data);
                }
            }
            this.dataGridView.DataSource = dlist;
        }
        public void reset()
        {

            listenClientThread.Resume();
        }
        //监听客户端连接
        private void Listen(object obj)
        {

            Socket serverSocket = (Socket)obj;
            while (true)
            {
                Socket tcp1 = serverSocket.Accept();
                IPAddress clientIP = (tcp1.RemoteEndPoint as IPEndPoint).Address;
                int clientPort = (tcp1.RemoteEndPoint as IPEndPoint).Port;
                socketObj socketObj = new socketObj();
                socketObj.socket = tcp1;
                socketObj.index = cycleNum;
                cilentSocket.Add(socketObj);

                int count_connect= PortHelper.PortTcpConnection(localProt); // 连接数;
                   
                //让客户显示"连接成功的"的信息
                string sendmsg = "\r\n连接服务端成功！\r\n" + "本地IP:" + clientIP + "，本地端口" + clientPort.ToString();
                sendResultMsg(sendmsg);

                //中间主机请求数据
                ThreadPool.QueueUserWorkItem(new WaitCallback(SwapMsg), new thSock
                {
                    tcp1 = serverSocket,
                    tcp2 = tcp1,
                    indexThread = cycleNum++
                });
            }
        }
        public void SwapMsg(object obj)
        {
            thSock mSocket = (thSock)obj;
            

            while (m_StopListen)
            {
                if (mSocket.indexThread.ToString() != cycleNumIndex.ToString())
                {
                    try
                    {
                        bytes = new byte[1024];
                        int num = mSocket.tcp2.Receive(bytes, bytes.Length, SocketFlags.None);
                        string str = Encoding.Default.GetString(bytes);
                        sendResultMsg("\r\n服务器端口接收数据:" + num);
                        if (str.Contains("u"))
                        {
                            str = str.Replace("u:", "");
                            foreach (socketObj sobj in  cilentSocket)
                            {
                                if (mSocket.indexThread.ToString().Equals(sobj.index.ToString())) {
                                    sobj.name = str;
                                }
                            }
                        }
                        if (num == 0) //接受空包关闭连接
                        {
                            sendResultMsg("\r\n断开连接:"+ mSocket.tcp2.RemoteEndPoint);
                            if (mSocket.tcp2.Connected)
                            {
                                mSocket.tcp2.Close();
                            }

                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        if (mSocket.tcp2.Connected)
                        {
                            mSocket.tcp2.Close();
                        }

                        break;
                    }
                }
                else
                {

                }
            }
        }
        public class thSock
        {
            public Socket tcp1 { get; set; }
            public Socket tcp2 { get; set; }

            public int indexThread { set; get; }
        }

        public class socketObj
        {
            public Socket socket { set; get; }
            public string name { set; get; }
            public int index { set; get; }


        }
    }
    class DataList
     {
        public string ip { set; get; }
        public string name { set; get; }
        
        public int index { set; get; }
        public DataList(string ip, string name)
        {
            this.ip = ip;
            this.name = name;
        }
    }
}
